# -*- encoding:utf8 -*-
"""
1. annual_base(staff) 计算员工的年假基数
2. annual_accum(staff) 计算员工今年到目前已经累积的年假

"""
from django.utils import timezone
from django.dispatch import receiver
from django.db.models import F
from attendance.convert import str2date,i2t,t2i
from attendance.models import AvaiLeave,LeaveModel
from attendance.tool_func import get_or_none

def update_annual(staff):
    """更新今年的累积年假
    """
    now=timezone.now().date()
    thisyear_str = '%s-01-01' % now.year
    this,created=AvaiLeave.objects.get_or_create(staff=staff,start_date=thisyear_str,category='annual_leave')
    this.span=i2t(annual_accum(staff))
    this.save()
    
def annual_left(staff):
    this=annual_left_this(staff)
    last=annual_left_last(staff)
    neg=annual_unmatch(staff)
    return this+last-neg

def annual_left_this(staff):
    """
    获取今年年假剩余
    """
    update_annual(staff)
    
    now=timezone.now().date()
    thisyear_str = '%s-01-01' % now.year
    this_leave,created=AvaiLeave.objects.get_or_create(staff=staff, start_date=thisyear_str,category='annual_leave')
    return this_leave.left()

def annual_unmatch(staff):
    """ToDo:年假预支的部分
    """
    leave=get_or_none(LeaveModel,staff=staff,matched=False,category='annual_leave')
    if leave:
        return leave.span()
    else:
        return 0
    
def annual_left_last(staff):
    """
    获取去年以前的所有未清空的年假
    """
    now=timezone.now().date()
    lastyear_str = '%s-01-01' % (now.year - 1)
    last2_str = '%s-01-01' % (now.year - 2)
    lastleft=0
    for accum_annul in AvaiLeave.objects.filter(staff=staff,start_date__lte=lastyear_str,is_valid=True,span__gt=F('used')):
        lastleft+=accum_annul.left()
    return lastleft

def annual_used_this(staff):
    yearstr='%s-01-01'%timezone.now().year
    avai=get_or_none(AvaiLeave,staff=staff,category='annual_leave',start_date=yearstr)
    if avai:
        return t2i(avai.used)
    else:
        return 0

def annual_base(staff):
    return _annual_base1(str2date(staff.startjob_date), str2date(staff.on_board_date))

def _annual_base1(startjob,startmoki):
    """
    从员工计算年假基数
    """
    #startjob= str2date(staff.startjob_date)
    #startmoki= str2date( staff.on_board_date)
    now = timezone.now().date()
    totalyear = _totalyear(startjob, now)
    mokiyear = _mokieyear(startmoki, now)
    legal_al = _legal_al(totalyear)
    moki_al = _mokie_al(mokiyear)
    # 年假的累积基数
    return _annual_base(legal_al, moki_al)
    

def annual_accum(staff):
    """
    获取今年的年假累积
    Args:
    staff:staffinfo员工对象
    """
    if all([staff.startjob_date,staff.on_board_date]):
        startjob= str2date(staff.startjob_date)
        startmoki= str2date( staff.on_board_date)
    elif staff.on_board_date:
        startjob=str2date(staff.on_board_date)
        startmoki= str2date( staff.on_board_date)
    else:
        # 没有moki入职时间，资料不能计算
        return
        
    return _annual_accum(startjob,startmoki)

def _annual_accum(startjob, startmoki):
    """
    获取累积的年假
    
    Args
    startjob:date
    startmoki:date
    
    Return:
    返回的是当年累积的年假(分钟)
    """
    nowdate = timezone.now().date()
    base = _annual_base1(startjob,startmoki) #get_exp(startjob, startmoki, due).get('annual_base')
    jobpoint = startjob.replace(year=nowdate.year)
    mokipoint = startmoki.replace(year=nowdate.year)
    p0 = nowdate.replace(month=1, day=1)
    if p0 < startmoki:
        p0 = startmoki
    p1 = min(jobpoint, mokipoint)
    p2 = max(jobpoint, mokipoint)

    if nowdate <= p1:
        rt = (nowdate - p0).days * base / 365.0
    elif p1 < nowdate <= p2:
        rt = (p1 - p0).days * base / 365.0 + \
             (nowdate - p1).days * base / 365.0
    elif p2 < nowdate:
        rt = (p1 - p0).days * base / 365.0 + \
             (p2 - p1).days * base / 365.0 + \
             (nowdate - p2).days * base / 365.0
    return int(rt * 60 * 8)



def _totalyear(startjob, due=None):
    if due is None:
        due = timezone.now().day()
    return yearspan(due, startjob)


def _mokieyear(startmoki, due=None):
    if due is None:
        due = timezone.now().day()
    return yearspan(due, startmoki)


def _legal_al(totalyear):
    """
     计算法定年假
    """
    if totalyear < 1:
        return 0
    elif 1 <= totalyear < 10:
        return 7
    elif 10 <= totalyear < 20:
        return 10
    else:
        return 15


def _mokie_al(mokiyear):
    return mokiyear


def _annual_base(legal_al, moki_al):
    """年假的累积基数，即原来HR命名的“本年度年假天数”
    legal_al:int
    moki_al:int
    """
    return min(20, legal_al + moki_al)


def yearspan(date1, date2):
    """
    date1 later than date2
    """

    year = date1.year - date2.year
    if date1.month > date2.month:
        return year
    elif date1.day > date2.day:
        return year
    else:
        return year - 1



#if __name__ == '__main__':
    #import unittest



    #unittest.main()
